$webwork.htmlEncode($page.space.name) : 1.3 Style Your Map
This page last changed on Dec 19, 2006 by bowens.
A quick tutorial on how to create and use SLD files to style your map Introduction Tutorial to Styled Layer DescriptorsStyled Layer Descriptors, or SLD, are what make your maps colorful. They tell the server how the map should be rendered; whether to draw lines in black, or to color them in blue with a nice outline and text labels. They can turn your map from plain: to nice: SLD is an XML based language detailed in an open specification available here. This means that SLD files created for GeoServer can be re-used with any WMS that supports SLD. We don't want lock you in to learning yet another way to style maps, so we put the open standard SLD at the center of GeoServer's rendering system. Now to get even the first image, you need an SLD. Lets look and see how we will do that... 1. SLD Hello WorldWe will start by creating a simple style for lines. 1.1 Create the SLD FileSTEP 1 <?xml version="1.0" encoding="ISO-8859-1"?> <StyledLayerDescriptor version="1.0.0" xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <NamedLayer> <Name>Default Line</Name> <UserStyle> <Title>A boring default style</Title> <Abstract>A sample style that just prints out a green line</Abstract> <FeatureTypeStyle> <!-- Rule 1 --> <Rule> <Name>Rule 1</Name> <Title>Green Line</Title> <Abstract>A green line with a 2 pixel width</Abstract> <LineSymbolizer> <Stroke> <CssParameter name="stroke">#319738</CssParameter> <CssParameter name="stroke-width">2</CssParameter> </Stroke> </LineSymbolizer> </Rule> </FeatureTypeStyle> </UserStyle> </NamedLayer> </StyledLayerDescriptor> The important part, to you, is the <rule>. This will describe what to draw and how to draw it. You can have as many rules as you want. This rule has no restrictions, so it will draw every line in green with a 2 pixel width. The element that is actually specifying how to draw is the <LineSymbolizer>. In this element we specify the color of the line, <CssParameter name="stroke">#319738</CssParameter>, and the width of the line, <CssParameter name="stroke-width">2</CssParameter>. 1.2 Load Your New SLDSTEP 2 In this window, hit new on the left side of the navigation bar: STEP 3 STEP 4
STEP 5 1.3 Give a FeatureType Your New SLDIn order to see what our style looks like, we need to tell a FeatureType what style to use. Then, whenever we view that FeatureType with the WMS, we will see our style. STEP 6 We now need to select an existing layer and change its Style. For this tutorial, we will select on of the FeatureTypes that comes installed with GeoServer: tasmania_roads:tasmania_roads Once you have selected it, hit the 'Edit' button. STEP 7 STEP 8 View the StyleIt is now time to look at the new style we made. STEP 9 This page shows you all of the enabled FeatureTypes you have. Locate the topp:tasmania_roads FeatureType and then click on the Preview button to the right of it. This will open up a new window with a MapBuilder view of the dataset. You can also click on this link http://localhost:8080/geoserver/data/generated/topp_tasmania_roads.html to view it. Hopefully you will see this: 2. SLD Text SymbolizersWe will continue from the previous example where we made a style, lines.sld, that rendered lines green and 2 pixels thick. This time we will add text to the lines that will be read from the roads themselves. Modify the SLD File to Include Text SymbolizersSTEP 1 <?xml version="1.0" encoding="ISO-8859-1"?> <StyledLayerDescriptor version="1.0.0" xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <NamedLayer> <Name>Default Line</Name> <UserStyle> <Title>A boring default style</Title> <Abstract>A sample style that just prints out a green line</Abstract> <FeatureTypeStyle> <!-- Rule 1 --> <Rule> <Name>Rule 1</Name> <Title>Green Line</Title> <Abstract>A green line with a 2 pixel width</Abstract> <LineSymbolizer> <Stroke> <CssParameter name="stroke">#319738</CssParameter> <CssParameter name="stroke-width">2</CssParameter> </Stroke> </LineSymbolizer> <TextSymbolizer> <Label> <ogc:PropertyName>TYPE</ogc:PropertyName> </Label> <Font> <CssParameter name="font-family">Times New Roman</CssParameter> <CssParameter name="font-style">Normal</CssParameter> <CssParameter name="font-size">16</CssParameter> <CssParameter name="font-weight">bold</CssParameter> </Font> <Fill> <CssParameter name="fill">#FF0000</CssParameter> </Fill> </TextSymbolizer> </Rule> </FeatureTypeStyle> </UserStyle> </NamedLayer> </StyledLayerDescriptor> The part that has changed is the adition of the <TextSymbolizer> element: <TextSymbolizer> <Label> <ogc:PropertyName>TYPE</ogc:PropertyName> </Label> <Font> <CssParameter name="font-family">Times New Roman</CssParameter> <CssParameter name="font-style">Normal</CssParameter> <CssParameter name="font-size">16</CssParameter> <CssParameter name="font-weight">bold</CssParameter> </Font> <Fill> <CssParameter name="fill">#FF0000</CssParameter> </Fill> </TextSymbolizer> The parts of this <TextSymbolizer> are:
There are other options, but we are just going to do something simple for now. STEP 2 Head back over to the config/data/style/ page in GeoServer and select your style, lines, from the drop down list. Then hit the 'Edit' button. STEP 3 STEP 4 STEP 5 The image should look something like this: What you will see is the TYPE of the roads displayed. It will not render the label on all of the roads, it will only render the unique values so the road names won't clobber each other. This can become difficult if there are two nearby roads with the same name, but aren't actually the same road. You will get one with a label and one without. To fix this simply add the tag: For an indepth document about Labeling, visit the Labeling Options page. 3. Outlines and FiltersThis is a very brief introduction to using filters and other text symbolizer techniques with SLDs. The following SLD document will render all non-highways in the regular green color with a red label. But it will also render the highways with an outline, and give their label an outline. Here is the SLD: <?xml version="1.0" encoding="ISO-8859-1"?> <StyledLayerDescriptor version="1.0.0" xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <NamedLayer> <Name>Default Line</Name> <UserStyle> <Title>A boring default style</Title> <Abstract>A sample style that just prints out a green line</Abstract> <FeatureTypeStyle> <!-- Rule 1 --> <Rule> <Name>Rule 1</Name> <Title>Green Line</Title> <Abstract>A green line with a 2 pixel width</Abstract> <ogc:Filter> <ogc:Not> <ogc:PropertyIsEqualTo> <ogc:PropertyName>TYPE</ogc:PropertyName> <ogc:Literal>highway</ogc:Literal> </ogc:PropertyIsEqualTo> </ogc:Not> </ogc:Filter> <LineSymbolizer> <Stroke> <CssParameter name="stroke">#319738</CssParameter> <CssParameter name="stroke-width">2</CssParameter> </Stroke> </LineSymbolizer> <TextSymbolizer> <Label> <ogc:PropertyName>TYPE</ogc:PropertyName> </Label> <Font> <CssParameter name="font-family">Times New Roman</CssParameter> <CssParameter name="font-style">Normal</CssParameter> <CssParameter name="font-size">16</CssParameter> <CssParameter name="font-weight">bold</CssParameter> </Font> <Fill> <CssParameter name="fill">#FF0000</CssParameter> </Fill> </TextSymbolizer> </Rule> <!-- Rule 2 --> <Rule> <Name>Rule 2</Name> <Title>Outlined Highways</Title> <Abstract>A gray outline and white fill, with a 8 pixel width</Abstract> <ogc:Filter> <ogc:PropertyIsEqualTo> <ogc:PropertyName>TYPE</ogc:PropertyName> <ogc:Literal>highway</ogc:Literal> </ogc:PropertyIsEqualTo> </ogc:Filter> <LineSymbolizer> <Stroke> <CssParameter name="stroke">#444444</CssParameter> <CssParameter name="stroke-width">8</CssParameter> </Stroke> </LineSymbolizer> <LineSymbolizer> <Stroke> <CssParameter name="stroke">#999999</CssParameter> <CssParameter name="stroke-width">4</CssParameter> </Stroke> </LineSymbolizer> <TextSymbolizer> <Label> <ogc:PropertyName>TYPE</ogc:PropertyName> </Label> <Font> <CssParameter name="font-family">Times New Roman</CssParameter> <CssParameter name="font-style">Normal</CssParameter> <CssParameter name="font-size">18</CssParameter> <CssParameter name="font-weight">bold</CssParameter> </Font> <Halo> <Radius> <ogc:Literal>2</ogc:Literal> </Radius> <Fill> <CssParameter name="fill">#FFF88B</CssParameter> <CssParameter name="fill-opacity">0.85</CssParameter> </Fill> </Halo> <Fill> <CssParameter name="fill">#FF0000</CssParameter> </Fill> </TextSymbolizer> </Rule> </FeatureTypeStyle> </UserStyle> </NamedLayer> </StyledLayerDescriptor> What we have done is supply another rule to our SLD. Rule 1The first rule will render all non-highways with a green line. To determine what roads are not highways, we use a <filter>: <ogc:Filter> <ogc:Not> <ogc:PropertyIsEqualTo> <ogc:PropertyName>TYPE</ogc:PropertyName> <ogc:Literal>highway</ogc:Literal> </ogc:PropertyIsEqualTo> </ogc:Not> </ogc:Filter> This rule will only render the line if its 'TYPE' is not equal to "highway". The 'not' is specified by wrapping the "PropertyIsEqualTo" element in an <ogc:Not> element. Other useful filter elements are:
Rule 2This rule uses a filter to determine if the road's TYPE is equal to "highway". If it is, it will render two lines for the road. The first is a thick dark gray line, the other is a thinner light gray line. They are rendered in the order that they are specified. The other thing it will do is render the labels using a <halo> in the <TextSymbolizer>. The halo is essentially a buffer outline of the text. <Halo> <Radius> <ogc:Literal>2</ogc:Literal> </Radius> <Fill> <CssParameter name="fill">#FFF88B</CssParameter> <CssParameter name="fill-opacity">0.85</CssParameter> </Fill> </Halo> OutputIf it all worked out, the result should look something like this: 4. What SLDs are, a text approachSLD (Styled Layer Descriptor) is a specification put out by the OGC, that defines an XML language to allow users to define symbolization of their feature data. It was written to be a complement to their Web Map Service (WMS) specification, by extending it to allow users a way to define how they want to visualize their features. The spec is available here? In the original WMS versions a user could ask for a 'style', specified by name, to view the map in. Each server advertised what 'styles' could be asked for with which layers. This was pretty inflexible, the only control a user had was to pick a name for a style, if the map didn't look the way she wanted it to then that was just too bad. It became obvious that it would be nice for users to be able to tell a server what they would actually like the style to look like. And thus came SLD, a nice little xml language for machines to understand how a human would like a map to look. So for each layer you could say 'color all my line features blue', or 'make all polygon borders black, and the insides purple', or even 'use this little triangle graphic for all my points'. But you can also define even more complex functionality. You can define the style rules based on attributes of the features in a layer. To pull an example from the SLD spec itself: The spec was originally meant for WMS, you could define an SLD document and send it to a server, and it would return the layer in the style you specified. But it has proven more useful than that. One way is to combine it with a WFS. There is a notion of a Cascading WMS, which would just be a middle layer between a WFS, adding the appropriate style and portraying it as the user wanted. A WFS defines the data, the WMS just adds the style information. GeoServer plans to have cascading WMS capabilities for version 1.3. The other place it's proven useful is as part of applications themselves. A good client could take a SLD file and apply that to the WFS response (GML) that it receives (this is what Sonny's client does, it's actually outside the original reason for the SLD spec, but a good use of it, as an SLD file could be passed to different clients ? you can send the WFS link and an SLD, so that they could actually get the data, instead of just a WMS response, which is simply a picture of the data). It's also useful as a way to define styles on the server itself. In OGC speak these are 'named' styles, as opposed to user defined ones. For user defined you send an sld document directly to the server, for a named one you just request the style by it's name. This is what GeoServer does, as there was already SLD support in GeoTools, and it's a solid way to define styles. GeoServer's styles are configured directly by reading SLD files. There is also having SLD files themselves be passed about the read. I believe there was a discussion spec for a server that would hold SLD files, and you could request them from the server, a sort of SLD service. The SLD extensions to a WMS also describe PutStyle and GetStyle operations, where a user could upload his style to the server, and others could download the files themselves. I don't have time right now to run through a bunch of sample SLD files, which I will in a final tutorial. You can refer to 'named' styles, but the more interesting part is the user defined stuff. There are two main sections for user defined styles (I think, I need to research this more, my SLD skills aren't nearly as strong as my WFS skills). A Rule defines in what cases the style should be applied. They can use the whole suite of OGC filters, so you really can define a lot. Complex stuff like coloring based on math expressions (add the unemployed, underemployed and temporary employed attributes, divide by total number of people, to give percentage of workers at less than full employment, and define the opacity based on the resulting number). They can also be defined for map scales, so things like only show two lane highways when we are at a certain resolution In a rule you can also define a 'legend graphic', which will show what means what on the map, by pointing to some external file (GeoServer has aspirations to create dynamic legend graphics based on the SLD definitions). Then there are 5 types of symbolizers you can use to actually portray the features, line, polygon, point, text, and raster. A line symbolizer will define a 'stroke' for a line geometry. A stroke is made up of a couple elements, allowing you to specify a color, or a graphic, along with things like opacity, width, joins between lines, a dash pattern and a dash offset. A Polygon Symbolizer has a geometry and a stroke, just like a line symbolizer, but also has a 'fill', defining what color to put in the center. Can be straight color, or a graphic, of varying opacity and the like. A point symbolizer is made up of a geometry and a Graphic. A graphic is made of either an External Graphic, or a Mark, and has an opacity, a size, and a rotation. Opacity is the same as for the other symbolizers, Size is the absolute size of the graphic in pixels (default is to be dynamic), and rotation defines the rotation of the graphic in the clockwise dimension in decimal degrees. A Mark has a well known name (like square, circle, star, ect.), and a fill and a stroke. An External Graphic uses an xlink to refer to the location of an resource on the web to use to represent the point. (Need to wrap this up, so my explanations are getting shorter). A text symbolizer is made up of a Geometry, a Label, a Font, a LabelPlacement, a Halo, and a Fill. A raster symbolizer consists of a Geometry, opacity, channel selection, overlap behavior, color map, contrast enhancement, shaded relief and image outline. (please excuse the lack of formatting and far from complete information, I will come back to it) 5. Further ReadingIf you have gotten this far, why not go further? Check out the GeoServer docs page for more information on SLDs, and read up on the SLD specification to see all the tags you can use. It is a good read. Also, head back to our main SLD page, especially Dave's advanced style tutorial. |
Document generated by Confluence on Jan 16, 2008 23:27 |